"""
认证路由模块
处理用户登录、注册、登出等认证功能
"""
from datetime import datetime
from flask import render_template, redirect, url_for, flash, request, jsonify
from flask_login import login_user, logout_user, current_user
from app.auth import bp
from app.models import User
from app import db
import re

def validate_email(email):
    """
    验证邮箱格式
    
    Args:
        email: 邮箱地址
    
    Returns:
        bool: 邮箱格式是否正确
    """
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return re.match(pattern, email) is not None

def validate_username(username):
    """
    验证用户名格式
    
    Args:
        username: 用户名
    
    Returns:
        bool: 用户名格式是否正确
    """
    # 用户名只能包含字母、数字、下划线，长度3-20
    pattern = r'^[a-zA-Z0-9_]{3,20}$'
    return re.match(pattern, username) is not None

@bp.route('/login', methods=['GET', 'POST'])
def login():
    """
    用户登录
    GET: 显示登录表单
    POST: 处理登录请求
    """
    # 如果用户已登录，重定向到首页
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    
    if request.method == 'POST':
        try:
            data = request.get_json() if request.is_json else request.form
            
            username = data.get('username', '').strip()
            password = data.get('password', '')
            remember_me = data.get('remember_me', False)
            
            # 验证输入
            if not username or not password:
                message = '请输入用户名和密码'
                if request.is_json:
                    return jsonify({'success': False, 'message': message}), 400
                flash(message, 'error')
                return render_template('login.html', title='登录')
            
            # 查找用户
            user = User.query.filter_by(username=username).first()
            
            # 验证用户和密码
            if user is None or not user.check_password(password):
                message = '用户名或密码错误'
                if request.is_json:
                    return jsonify({'success': False, 'message': message}), 401
                flash(message, 'error')
                return render_template('login.html', title='登录')
            
            # 检查用户是否被禁用
            if not user.is_active:
                message = '账号已被禁用，请联系管理员'
                if request.is_json:
                    return jsonify({'success': False, 'message': message}), 403
                flash(message, 'error')
                return render_template('login.html', title='登录')
            
            # 登录用户
            login_user(user, remember=remember_me)
            
            # 更新最后登录时间
            user.last_login = datetime.utcnow()
            db.session.commit()
            
            # 根据用户角色重定向
            next_page = request.args.get('next')
            if not next_page or not next_page.startswith('/'):
                if user.is_admin():
                    next_page = url_for('admin.dashboard')
                else:
                    next_page = url_for('main.inbox')
            
            if request.is_json:
                return jsonify({
                    'success': True, 
                    'message': '登录成功',
                    'redirect': next_page,
                    'user': user.to_dict()
                })
            
            flash(f'欢迎回来，{user.username}！', 'success')
            return redirect(next_page)
            
        except Exception as e:
            db.session.rollback()
            message = f'登录失败：{str(e)}'
            if request.is_json:
                return jsonify({'success': False, 'message': message}), 500
            flash(message, 'error')
    
    return render_template('login.html', title='登录')

@bp.route('/register', methods=['GET', 'POST'])
def register():
    """
    用户注册
    GET: 显示注册表单
    POST: 处理注册请求
    """
    # 如果用户已登录，重定向到首页
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    
    # 班级选项 (0-10)
    class_options = [
        {'id': 0, 'name': '其他班级'},
        {'id': 1, 'name': '1班'},
        {'id': 2, 'name': '2班'},
        {'id': 3, 'name': '3班'},
        {'id': 4, 'name': '4班'},
        {'id': 5, 'name': '5班'},
        {'id': 6, 'name': '6班'},
        {'id': 7, 'name': '7班'},
        {'id': 8, 'name': '8班'},
        {'id': 9, 'name': '9班'},
        {'id': 10, 'name': '10班'}
    ]
    
    if request.method == 'POST':
        try:
            data = request.get_json() if request.is_json else request.form
            
            # 获取表单数据
            username = data.get('username', '').strip()
            password = data.get('password', '')
            confirm_password = data.get('password2', '')
            real_name = data.get('real_name', '').strip()
            class_id = data.get('class_id')
            
            # 验证必填字段
            if not all([username, password, confirm_password, real_name]):
                return jsonify({'success': False, 'message': '请填写所有必填字段'}), 400
            
            # 验证班级ID
            if class_id is None:
                return jsonify({'success': False, 'message': '请选择班级'}), 400
            
            try:
                class_id = int(class_id)
                if class_id < 0 or class_id > 10:
                    return jsonify({'success': False, 'message': '班级号必须在0-10之间'}), 400
            except (ValueError, TypeError):
                return jsonify({'success': False, 'message': '班级号格式错误'}), 400
            
            # 验证输入
            errors = []
            
            if not validate_username(username):
                errors.append('用户名只能包含字母、数字、下划线，长度3-20位')
            
            if len(password) < 6:
                errors.append('密码长度至少6位')
            
            if password != confirm_password:
                errors.append('两次输入的密码不一致')
            
            if len(real_name) < 2 or len(real_name) > 20:
                errors.append('真实姓名长度应在2-20个字符之间')
            
            # 检查用户名是否已存在
            if username and User.query.filter_by(username=username).first():
                errors.append('用户名已存在')
            
            # 自动生成学生邮箱地址
            email = f"{username}@wxxx.com"
            
            # 检查生成的邮箱是否已存在
            if User.query.filter_by(email=email).first():
                errors.append('生成的邮箱地址已被使用，请更换用户名')
            
            if errors:
                message = '；'.join(errors)
                if request.is_json:
                    return jsonify({'success': False, 'message': message}), 400
                for error in errors:
                    flash(error, 'error')
                return render_template('register.html', title='注册', class_options=class_options)
            
            # 创建新用户
            user = User(
                username=username,
                email=email,
                role='student',
                real_name=real_name,
                class_id=class_id
            )
            user.set_password(password)
            
            db.session.add(user)
            db.session.commit()
            
            message = f'注册成功！欢迎 {real_name}（{username}），请登录使用系统。'
            if request.is_json:
                return jsonify({
                    'success': True, 
                    'message': message,
                    'redirect': url_for('auth.login')
                })
            
            flash(message, 'success')
            return redirect(url_for('auth.login'))
            
        except Exception as e:
            db.session.rollback()
            message = f'注册失败：{str(e)}'
            if request.is_json:
                return jsonify({'success': False, 'message': message}), 500
            flash(message, 'error')
    
    return render_template('register.html', title='注册', class_options=class_options)

@bp.route('/logout')
def logout():
    """
    用户登出
    """
    if current_user.is_authenticated:
        username = current_user.username
        logout_user()
        flash(f'再见，{username}！', 'info')
    
    return redirect(url_for('auth.login'))

@bp.route('/check_username')
def check_username():
    """
    检查用户名是否可用
    """
    username = request.args.get('username', '').strip()
    
    if not username:
        return jsonify({'available': False, 'message': '用户名不能为空'})
    
    if not validate_username(username):
        return jsonify({'available': False, 'message': '用户名格式不正确'})
    
    user = User.query.filter_by(username=username).first()
    if user:
        return jsonify({'available': False, 'message': '用户名已存在'})
    
    return jsonify({'available': True, 'message': '用户名可用'})

@bp.route('/check_email')
def check_email():
    """
    检查邮箱是否可用
    """
    email = request.args.get('email', '').strip()
    
    if not email:
        return jsonify({'available': False, 'message': '邮箱不能为空'})
    
    if not validate_email(email):
        return jsonify({'available': False, 'message': '邮箱格式不正确'})
    
    user = User.query.filter_by(email=email).first()
    if user:
        return jsonify({'available': False, 'message': '邮箱已被注册'})
    
    return jsonify({'available': True, 'message': '邮箱可用'})

@bp.route('/profile')
def profile():
    """
    用户个人资料页面
    """
    if not current_user.is_authenticated:
        return redirect(url_for('auth.login'))
    
    return render_template('profile.html', title='个人资料', user=current_user)

@bp.route('/change_password', methods=['POST'])
def change_password():
    """
    修改密码
    """
    if not current_user.is_authenticated:
        return jsonify({'success': False, 'message': '请先登录'}), 401
    
    try:
        data = request.get_json()
        
        old_password = data.get('old_password', '')
        new_password = data.get('new_password', '')
        confirm_password = data.get('confirm_password', '')
        
        # 验证输入
        if not old_password or not new_password or not confirm_password:
            return jsonify({'success': False, 'message': '请填写完整信息'}), 400
        
        # 验证原密码
        if not current_user.check_password(old_password):
            return jsonify({'success': False, 'message': '原密码错误'}), 400
        
        # 验证新密码
        if len(new_password) < 6:
            return jsonify({'success': False, 'message': '新密码长度至少6位'}), 400
        
        if new_password != confirm_password:
            return jsonify({'success': False, 'message': '两次输入的新密码不一致'}), 400
        
        # 更新密码
        current_user.set_password(new_password)
        db.session.commit()
        
        return jsonify({'success': True, 'message': '密码修改成功'})
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': f'修改失败：{str(e)}'}), 500